import base64
import json
import re
# import time

import requests
import ddddocr
from lxml import html
from src import utils

ocr = ddddocr.DdddOcr()


class VerificationCaptcha:
    def __init__(self, captcha_id, cookies, is_login):
        self.captcha_url = 'https://spain.blscn.cn' + captcha_id
        self.is_login = is_login
        self.cookies = cookies

    def get_captcha_data(self):
        htmlResponse = requests.get(self.captcha_url, headers=utils.get_headers(), cookies=self.cookies)
        if htmlResponse.status_code == 200:
            # 将二进制内容写入本地文件
            tree = html.fromstring(htmlResponse.content)
            captchaData = getCaptchaData(tree)
            style_tags = tree.xpath('//style')
            z_index_map, empty_map = get_css_properties(style_tags[0].text)
            target_code = get_target_code(tree, z_index_map)
            ids = get_img_code(tree, empty_map)
            select_ids = get_select_id(tree, ids, target_code)
            captchaData['SelectedImages'] = ','.join(select_ids)
            val = self.valiCaptcha(captchaData)
            if val is None:
                with open('captcha.html', 'wb') as file:
                    file.write(htmlResponse.content)
                print(select_ids)
            return val

    def valiCaptcha(self, data):
        headers = utils.get_headers()
        submit_url = 'https://spain.blscn.cn/CHN/CaptchaPublic/SubmitCaptcha' if self.is_login else 'https://spain.blscn.cn/CHN/NewCaptcha/SubmitCaptcha'
        res = requests.post(submit_url, data=data, headers=headers,
                            cookies=self.cookies)
        if res.status_code == 200:
            json_obj = json.loads(res.content)
            if json_obj['success']:
                return json_obj['captcha'] or json_obj['cd']


def get_select_id(tree, ids, target_code):
    # 遍历所有的规则
    new_list = []
    for id in ids:
        images = tree.xpath('//div[@id="' + id + '"]/img')
        imgSrc = images[0].get('src')
        imgCode = ocr.classification(base64.b64decode(imgSrc.replace('data:image/gif;base64,', '')))
        # print(id + ':' + imgCode)
        if adapter(imgCode) == target_code:
            new_list.append(id)
    return new_list


def adapter(imgCode):
    if 'H' in imgCode:
        return imgCode.replace('H', '11')
    if 'o' in imgCode:
        return imgCode.replace('o', '0')
    if 'O' in imgCode:
        return imgCode.replace('O', '0')
    if 'l' in imgCode:
        return imgCode.replace('l', '1')

    return imgCode


def get_img_code(tree, empty_map):
    divs = tree.xpath('//div[contains(@class, "col-4")]')
    displayList = []
    for div in divs:
        if div.get('id') is not None:
            class_list = div.get('class').split(' ')
            if empty_map.get(class_list[1]) or empty_map.get(class_list[2]) or empty_map.get(class_list[3]):
                displayList.append(div.get('id'))
    return displayList


def get_target_code(tree, z_index_map):
    divs = tree.xpath('//div[contains(@class, "col-12") and contains(@class, "box-label")]')
    target_code = ''
    max_z_index = 0
    for div in divs:
        classNams = div.get('class').split(' ')
        className = classNams[2]
        index = z_index_map.get(className)
        if index is not None and index > max_z_index:
            max_z_index = index
            match = re.search(r'\d+', div.text)
            target_code = match.group()
    return target_code


def get_css_properties(style_text):
    # 创建一个字典来保存属性
    z_index_map = {}
    z_index_pattern = r'\.(\w+){z-index:(\d+);}'
    index_matches = re.findall(z_index_pattern, style_text)

    for match in index_matches:
        z_index_map[match[0]] = int(match[1])

    empty_map = {}
    empty_pattern = r'\.(\w+){}'
    empty_matches = re.findall(empty_pattern, style_text)

    for match in empty_matches:
        empty_map[match] = True

    return z_index_map, empty_map


def getCaptchaData(tree):
    __RequestVerificationToken = tree.xpath('//input[@name="__RequestVerificationToken"]')[0].get('value')
    Id = tree.xpath('//input[@id="Id"]')[0].get('value')
    data = {
        'SelectedImages': '',
        'Id': Id,
        '__RequestVerificationToken': __RequestVerificationToken,
        'X-Requested-With': 'XMLHttpRequest'
    }
    captcha = tree.xpath('//input[@id="Captcha"]')
    if len(captcha) != 0:
        data['Captcha'] = captcha[0].get('value')

    return data

